package com.hyacinth.cloudnote.modules.note.controller;

import com.hyacinth.cloudnote.common.constants.IConstants;
import com.hyacinth.cloudnote.common.dto.result.PageResultDTO;
import com.hyacinth.cloudnote.common.dto.result.ResultDTO;
import com.hyacinth.cloudnote.common.exception.ExceptionHolder;
import com.hyacinth.cloudnote.modules.note.converter.NoteConverter;
import com.hyacinth.cloudnote.modules.note.dto.NoteDTO;
import com.hyacinth.cloudnote.modules.note.model.Note;
import com.hyacinth.cloudnote.modules.note.model.QNote;
import com.hyacinth.cloudnote.modules.note.repository.NoteRepository;
import com.hyacinth.cloudnote.modules.note.service.NoteService;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import io.micrometer.core.annotation.Timed;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

import static com.hyacinth.cloudnote.modules.common.errorcode.NoteErrorCode.E1000000001;

/**
 * WasteBasket实体类对应的基础业务Controller
 * @author zhangfb
 */
@Slf4j
@RestController
@RequestMapping(value = "/w/wasteBaskets", produces = MediaType.APPLICATION_JSON_VALUE)
@Api(tags = {"WasteBasket管理API"}, produces = MediaType.APPLICATION_JSON_VALUE)
public class WasteBasketController {

    @Autowired
    private NoteService noteService;
    @Autowired
    private NoteRepository noteRepository;
    @Autowired
    private NoteConverter noteConverter;

    /**
     * 获取分页数据
     *
     * @param pageable 分页+排序参数
     * @return 分页数据
     */
    @Timed
    @ApiOperation(value = "获取分页数据")
    @RequestMapping(value = "/s", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public PageResultDTO<NoteDTO> search(@PageableDefault(sort = {IConstants.CONST_PAGEABLE_CREATED_DATE}, direction = Sort.Direction.DESC) final Pageable pageable,
                                         @QuerydslPredicate(root = Note.class) Predicate predicate) {
        predicate = ExpressionUtils.and(predicate, QNote.note.disable.isTrue());
        final Page<Note> models = this.noteRepository.findAll(predicate, pageable);
        return this.noteConverter.toResultDTO(models);
    }

    /**
     * 取得详细数据
     *
     * @param id 实体对象ID
     * @return 资源详细
     */
    @Timed
    @ApiOperation(value = "获取详细数据")
    @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
    public ResultDTO<NoteDTO> get(@PathVariable final UUID id) {
        final Note model = this.noteRepository.findById(id)
                .orElseThrow(() -> ExceptionHolder.serviceException(E1000000001, "笔记-" + id));
        return this.noteConverter.toResultDTOForView(model);
    }

    /**
     * 还原
     *
     * @param id 资源id
     * @return 资源对象
     */
    @Timed
    @ApiOperation(value = "还原")
    @PostMapping(value = "reduce/{id}")
    public ResultDTO<NoteDTO> reduce(@PathVariable final UUID id) {
        Note model = this.noteService.reduce(id);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was reduced.", Note.class.getSimpleName(), model.getId());
        }
        return this.noteConverter.toResultDTO(model);
    }

    /**
     * 彻底删除
     *
     * @param id 实体对象ID
     * @return 操作结果
     */
    @Timed
    @ApiOperation(value = "彻底删除")
    @DeleteMapping(value = "/{id}")
    public ResultDTO<Void> delete(@PathVariable final UUID id) {
        this.noteService.delete(id);
        if (log.isInfoEnabled()) {
            log.info("{} instance {} was deleted.", Note.class.getSimpleName(), id);
        }
        return ResultDTO.success();
    }
}
